package com.seeyon.ctp.rest.resources;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.seeyon.apps.ndk.kit.*;
import com.seeyon.cap4.form.bean.FormBean;
import com.seeyon.cap4.form.bean.FormFieldBean;
import com.seeyon.cap4.form.service.CAP4FormManager;
import com.seeyon.ctp.common.AppContext;
import com.seeyon.ctp.common.authenticate.domain.User;
import com.seeyon.ctp.common.flag.BrowserEnum;
import com.seeyon.ctp.common.log.CtpLogFactory;
import com.seeyon.ctp.organization.bo.V3xOrgEntity;
import com.seeyon.ctp.organization.bo.V3xOrgMember;
import com.seeyon.ctp.organization.manager.OrgManager;
import org.apache.commons.logging.Log;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Path("jssdk")
@Produces({MediaType.APPLICATION_JSON})
public class CustomBPMResources extends BaseResource {
    private static final Log log = CtpLogFactory.getLog(CustomBPMResources.class);

    private CAP4FormManager cap4FormManager = (CAP4FormManager) AppContext.getBean("cap4FormManager");
    private OrgManager orgManager = (OrgManager) AppContext.getBean("orgManager");

    private String localAddr = AppContext.getRawRequest().getLocalAddr();
    private String port = String.valueOf(AppContext.getRawRequest().getLocalPort());
    private String memberUrl = "http://" + localAddr + ":" + port + "/seeyon/rest/orgMember/";
    private String tokenUrl = "http://" + localAddr + ":" + port + "/seeyon/rest/token";
    private String bpmUrl = "http://" + localAddr + ":" + port + "/seeyon/rest/bpm/process/start";

    /**
     * 发送协作流程
     *
     * @param param 请求参数，以Map形式传入
     * @return 请求返回结果
     * @throws Exception 异常情况
     */
    @POST
    @Path("custom/bpm/collaboration")
    @Consumes(MediaType.APPLICATION_JSON)
    public Response sendCollaboration(Map<String, Object> param) throws Exception {
        log.info("SAP流程推送json入参:" + JSON.toJSONString(param));
        try {
            // 创建一个JSON对象，并将参数param转换为JSON格式
            JSONObject jsonObj = new JSONObject(param);

            String templateCode = "";
            // 如果JSON对象中包含"workflowId"键，则获取其对应的值并去除空格后赋给templateCode变量
            if (jsonObj.containsKey("workflowId")) {
                templateCode = StrKit.str(jsonObj.get("workflowId")).trim();
            }
            // 如果templateCode为空字符串，则返回错误信息，提示流程id不能为空
            if ("".equals(templateCode)) {
                return ok(MessageKit.error("E", "", "流程ID不能为空"));
            }

            // 根据templateCode获取对应的FormBean对象
            FormBean formBean = cap4FormManager.getFormByFormCode(templateCode);
            // 如果formBean为null，则返回错误信息，提示流程模版编码不存在
            if (formBean == null) {
                return ok(MessageKit.error("E", "", "流程ID[" + templateCode + "]不存在"));
            }

            // 如果JSON对象中包含"senderCode"键，则获取其对应的值并去除空格后赋给senderCode变量
            String senderCode = "";
            if (jsonObj.containsKey("senderCode")) {
                senderCode = StrKit.str(jsonObj.get("senderCode")).trim();
            }
            // 如果当前用户为null，则返回错误信息，提示发起人工号不能为空
            if ("".equals(senderCode)) {
                return ok(MessageKit.error("E", "", "发起人工号不能为空值"));
            }

            // 根据发起人工号获取组织成员列表
            List<V3xOrgEntity> orgMemberList = orgManager.getEntityList(V3xOrgMember.class.getSimpleName(), "code", senderCode, null, false, true);

            // 如果组织成员列表为空，则返回错误信息，提示发起人工号在OA系统中不存在
            if (orgMemberList.isEmpty()) {
                return ok(MessageKit.error("E", "", "发起人工号[" + senderCode + "]在OA系统中不存在"));
            }
            V3xOrgMember v3xOrgMember = (V3xOrgMember) orgMemberList.get(0);
            // 获取当前用户
            User user = AppContext.getCurrentUser();

            if (user == null) {
                /*将用户信息更新到当前线程*/
                User user_new = new User();
                user_new.setId(v3xOrgMember.getId());
                user_new.setLoginName(v3xOrgMember.getLoginName());
                user_new.setName(v3xOrgMember.getName());
                user_new.setAccountId(v3xOrgMember.getOrgAccountId());
                user_new.setBrowser(BrowserEnum.IE);
                user_new.setLoginAccount(v3xOrgMember.getOrgAccountId());
                AppContext.putThreadContext("SESSION_CONTEXT_USERINFO_KEY", user_new);
            }

            // 创建一个字符串和对象类型的映射表
            Map<String, Object> headers = new HashMap<String, Object>();
            String tokenId = HttpKit.getToken(v3xOrgMember.getLoginName(), tokenUrl);

            // 创建一个字符串与对象类型的映射表
            Map<String, Object> map = new HashMap<String, Object>();

            // 创建一个字符串与对象类型的映射表，用于存储表单数据
            Map<String, Object> formDataMap = new HashMap<String, Object>();
            // 将键"appName"和值"collaboration"添加到映射表map中
            map.put("appName", "collaboration");
            // 将键"draft"和值"0"添加到映射表formDataMap中
            formDataMap.put("draft", "0");
            // 将键"templateCode"和值templateCode添加到映射表formDataMap中
            formDataMap.put("templateCode", templateCode);

            // 创建一个字符串与对象类型的映射表，用于存储数据
            Map<String, Object> dataMap = new HashMap<String, Object>();
            // 创建一个空的附件数组
            JSONArray fileJsonArray = new JSONArray();
            // 如果JSON对象中存在"attachments"键
            if (jsonObj.containsKey("attachments")) {
                // 将"attachments"键对应的JSON数组赋值给fileJsonArray
                fileJsonArray = jsonObj.getJSONArray("attachments");
            }

            // 如果JSON对象中包含"mainData"键，则获取其对应的值并赋给mainObj变量
            if (jsonObj.containsKey("mainData")) {
                /*主表数据*/
                JSONArray mainJsonArray = jsonObj.getJSONArray("mainData");
                // 获取主表的字段列表
                List<FormFieldBean> mainFieldBeans = formBean.getMasterTableBean().getFields();
                // 获取主表的表名
                String mainTableName = formBean.getMasterTableBean().getTableName();
                // 从mainJsonArray和fileJsonArray中提取主要数据，并存储在mainDataMap中
                Map<String, Object> mainDataMap = JsonKit.mainData(mainJsonArray, fileJsonArray, mainFieldBeans);
                // 如果mainDataMap中包含键"thirdAttachments"，则将对应的值存入dataMap中的"thirdAttachments"键中
                if (mainDataMap.containsKey("thirdAttachments")) {
                    dataMap.put("thirdAttachments", mainDataMap.get("thirdAttachments"));
                }
                // 移除mainDataMap中的"thirdAttachments"键
                mainDataMap.remove("thirdAttachments");
                // 将主表数据中的"申请人"键的值更新为当前用户id
                mainDataMap.put("申请人", v3xOrgMember.getId());
                String deptId = DataConversionKit.getDeptIdByMemberLoginNameAndAccountId(tokenId, memberUrl, v3xOrgMember.getLoginName(), mainJsonArray);
                mainDataMap.put("申请部门", deptId);
                // 将主表数据以JSON格式存入dataMap中
                dataMap.put(mainTableName, mainDataMap);
            }

            // 如果JSON对象中包含"detailData"键，则获取其对应的值并赋给subJsonArray变量
            if (jsonObj.containsKey("detailData")) {
                /*子表数据*/
                JSONArray subJsonArray = jsonObj.getJSONArray("detailData");
                // 如果子json数组不为空
                if (!subJsonArray.isEmpty()) {
                    Map<String, List<Map<String, Object>>> subDataMap = JsonKit.subData(subJsonArray, formBean);
                    if (!subDataMap.isEmpty()) {
                        for (String key : subDataMap.keySet()) {
                            dataMap.put(key, subDataMap.get(key));
                        }
                    }
                }
            }
            // 将dataMap添加到formDataMap中
            formDataMap.put("data", dataMap);
            // 将formDataMap添加到map中
            map.put("data", formDataMap);
            // 将map转换为JSON格式的字符串
            String dataJson = JSON.toJSONString(map);
            // 打印发送协同流程的JSON字符串
            log.info("发送协同流程json:" + dataJson);

            // 将获取到的token放入映射表中
            headers.put("token", tokenId);
            // 使用HttpKit工具类进行POST请求，返回结果保存在result变量中
            String result = HttpKit.post(bpmUrl, headers, dataJson);
            log.info("发送协同流程接口返回信息:" + result);
            String returnMsg = MessageKit.bpmMessage(result);
            log.info("发送协同流程接口返回SAP系统json字符串:" + returnMsg);
            return ok(returnMsg);
        } catch (Exception e) {
            log.error("发送协同流程接口异常", e);
            return ok(MessageKit.error("E", "", e.getMessage()));
        }
    }

}
